package com.fcgzs.config;

import com.fcgzs.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Auther: ljj
 * @Description:
 */
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    //定义令牌的key
    private static final String AUTHORIZE_TOKEN = "Authorization";

    //自定义登录路径
    private static final  String LOGIN_PATH="http://localhost:9100/oauth/login";


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.由exchange获取请求和响应的对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //2.在请求对象中获取请求路径
        String path = request.getURI().getPath();
        //3.判断不需要鉴权的请求，则直接放行
        if(path.startsWith("/api/user/login")||path.startsWith("/api/search/search")){
            Mono<Void> mono = chain.filter(exchange);
            return mono;
        }

        //4.需要鉴权的请求，获取令牌，在请求头信息中获取
        String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
        //5.如果头信息中没有令牌，则到请求属性中获取
        if(StringUtils.isEmpty(token)){
            token =  request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
        }


        //从Cookie中取得令牌
        HttpCookie cookie = request.getCookies().getFirst(AUTHORIZE_TOKEN);
        if(StringUtils.isEmpty(token)) {
            if(cookie!=null){
                if (cookie.getValue().startsWith("bearer")||cookie.getValue().startsWith("Bearer")) {
                    token = cookie.getValue();
                }else{
                    token = "bearer "+cookie.getValue();
                }
            }
        }

        //6.如果没有获取到令牌，则返回错误响应 405
        if(StringUtils.isEmpty(token)){
            //response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
            //return response.setComplete();
            //如果令牌为空，则未登录，需要跳转到登录页面
            return this.needAuthorization(LOGIN_PATH+"?FROM="+request.getURI().toString(),exchange);
        }



        //7.如果有令牌，则校验令牌，校验通过则请求放行
        try {
            //Claims claims = JwtUtil.parseJWT(token);
            if(token.startsWith("bearer")||token.startsWith("Bearer")){
                //则直接将请求通行
                request.mutate().header(AUTHORIZE_TOKEN,token);
            }else{
                request.mutate().header(AUTHORIZE_TOKEN,"bearer "+token);
            }

            //将令牌解析后的信息，放到请求头信息中，供后面的请求方法使用
            //request.mutate().header(AUTHORIZE_TOKEN,claims.toString());
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //放行
        return chain.filter(exchange);
    }


    private Mono<Void> needAuthorization(String url,ServerWebExchange exchange){
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.SEE_OTHER);
        response.getHeaders().set("Location",url);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
